package top.syfy.oss.aliyun.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import top.syfy.oss.aliyun.exception.BizException;
import top.syfy.oss.aliyun.exception.CommonEnum;
import top.syfy.oss.aliyun.response.ContentReturnType;
import top.syfy.oss.aliyun.util.FileUtil;
import top.syfy.oss.aliyun.util.OssUtil;
import java.io.IOException;
import java.util.Arrays;
import java.util.Objects;

/**
 * OSS应用层
 * 
 * @author awg
 * @date 2020/10/26
 */
@RestController
@RequestMapping(value = "/oss")
public class OssController {

    @Autowired
    private OssUtil ossUtil;

    /**
     * 允许上传文件的格式
     */
    @Value("${uposs.allowed-file-suffix}")
    private String ALLOWED_FILE_SUFFIX;

    /**
     * 允许上传文件的最大值(带有单位,如MB)
     */
    @Value("${uposs.allowed-file-size-max}")
    private String ALLOWED_FILE_MAX_SIZE;

    /**
     * 上传文件到OSS
     * 
     * @param file 上传的文件
     * @return 上传响应
     */
    @PostMapping(value = "/uploadfile")
    public ContentReturnType fileUpload(@RequestParam("img") MultipartFile file) {
        // 1.文件内容校验
        if (Objects.isNull(file)) {
            throw new BizException(CommonEnum.BODY_NOT_MATCH);
        }
        // 2.文件格式校验
        String originName = file.getOriginalFilename();
        String suffix = Objects.requireNonNull(originName).substring(originName.lastIndexOf(".") + 1).toUpperCase();
        if (!Arrays.asList(ALLOWED_FILE_SUFFIX.split(", *")).contains(suffix)) {
            throw new BizException(CommonEnum.FILE_SUFFIX_NOT_ALLOWED);
        }
        // 3.文件大小判断
        /*
          因为MultipartException在到达Controller层之前就被捕获并抛出了（并有return值），所以设置了全局捕获但捕获的MultipartException异常却无法正确返回对象给前端的原因（return值被提前处理）.
          解决方法:1.把Multipart对象文件大小上限(spring.servlet.multipart.max-file-size)设置成一个平时达不到的值;2.在Controller里有上传业务的接口里独立设置阀值。
         */
        if (!FileUtil.fileSizeJudge(file, ALLOWED_FILE_MAX_SIZE)) {
            throw new BizException(CommonEnum.FILE_SIZE_NOT_ALLOWED);
        }
        // 4.上传文件到OSS
        try {
            String url = ossUtil.uploadFile(file);
            return ContentReturnType.ofReturn(CommonEnum.SUCCESS, url);
        } catch (IOException e) {
            throw new BizException(CommonEnum.INTERNAL_SERVER_ERROR);
        }
    }

}
